/*
 * @Author: 王嘉龙
 * @Date: 2024-04-30 15:40:07
 * @LastEditors: 王嘉龙 1462604987@qq.com
 * @LastEditTime: 2024-12-24 10:04:47
 * @Description:
 */
#include "./BSP/device/device.h"
//#include "bootloader.h"
#include "boot_config.h"
#include "log.h"
#include "./BSP/STMFLASH/stmflash.h"
#include "string.h"

#include "stdlib.h"
#include <stdbool.h>
#include <stdarg.h>

qf_dev_t g_qf_device =
{
    .phy = {
        .Version = "1.0.0",
        .ID = 1,
        .MAC = {0xAA, 0xBB, 0xCC, 0xDD},
        .IP = {192, 168, 0, 240},
        .MASK = {255, 255, 255, 0},
        .Gateway = {192, 168, 0, 1},

        .DeviceID = "USB001",
        .DNS = {8, 8, 8, 8},
        .HEART_TICK = 60,
        .TIMEOUT = 90,
        .AGIP = {192, 168, 10, 206},
        .AGKEY = "6a3c0d61-a5d2-4ff8-aaf7-a3cda50a0e3c",
    },
    .info = {
        .Name = "admin",
        .PassWord = "admin",
        .Card = {""},
        .UsbUseStatus = {0}
    },
    .state = {
        .Factory_Reset = 0,
        .UsbExUseStatus = {0},
        .DefanceStatus = 0,
        .Buzz_Switch = 0,
    }};
qf_running_state_t g_running_state = {
    .chUsbLinkStatus = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};

qf_dev_t buf;

/**
 * @brief 初始化系统参数
 */
int Sys_Parameters_Init(void)
{
    
    stmflash_read(USER_DATA_ADDR,(uint16_t *)&buf,sizeof(qf_dev_t));
        
    if ((IsDataValidity((uint8_t *)&buf.phy.Version, 0xff, 3) == 0) ||
        IsDataValidity((uint8_t *)&buf.phy.Version, 0x00, 3) == 0)
    {
        // 系统参数未初始化，进行初始化
        buf.state.Factory_Reset = 1;
    }
    if( buf.state.Factory_Reset == 1 )
    {
        // 系统参数已初始化，但需要恢复出厂设置
//        log_info("恢复出厂设置\r\n");
        TerParamUpdate();
    }
    else
    {
        memcpy(&g_qf_device, &buf, sizeof(qf_dev_t));
    }
//    log_info("IP\t:%d,%d,%d,%d\n",g_qf_device.phy.IP[0],g_qf_device.phy.IP[1],g_qf_device.phy.IP[2],g_qf_device.phy.IP[3]);
//    log_info("Gateway\t:%d,%d,%d,%d\n",g_qf_device.phy.Gateway[0],g_qf_device.phy.Gateway[1],g_qf_device.phy.Gateway[2],g_qf_device.phy.Gateway[3]);
//    log_info("MASK\t:%d,%d,%d,%d\n",g_qf_device.phy.MASK[0],g_qf_device.phy.MASK[1],g_qf_device.phy.MASK[2],g_qf_device.phy.MASK[3]);
    return 0;
}

// 根据防区类型修正参数
void Revised_para(void)
{
#if USE_DEFENSE
    uint8_t i = 0;
    for (i = 0; i < 8; i++)
    {
        switch (g_qf_device.info.DZ_M_Attributes[i])
        {
        case DZ_ATTR_INSTANT: // 即时防区,可布撤防,不延时

            break;
        case DZ_ATTR_HOLD: // 留守防区,可布撤防,不延时

            break;
        case DZ_ATTR_FIRE: // 火警防区，不可撤防，不延时
            g_qf_device.info.DZ_M_Defense[i] = 1;
            break;
        case DZ_ATTR_24HOUR: // 24小时防区，不可布撤防，不延时
            g_qf_device.info.DZ_M_Defense[i] = 1;
            break;
        case DZ_ATTR_SILENT: // 静音防区，不可布撤防，不延时
            g_qf_device.info.DZ_M_Defense[i] = 1;
            break;
        case DZ_ATTR_EMERGENCY: // 紧急防区，不可布撤防，不延时
            g_qf_device.info.DZ_M_Defense[i] = 1;
            break;
        case DZ_ATTR_DELAY: // 延时防区,可布撤防,可延时
            break;
        case DZ_ATTR_BYPASS: // 旁路防区，可布撤防,不延时
            break;
        default:
            break;
        }
    }
#endif
}

/**
 * @description: 防区撤防
 * @param {uint8_t} number 传入ID号
 * @return {NULL}
 */
void Reset_defence(uint8_t number)
{
#if USE_DEFENSE
    uint8_t i;
    switch (number)
    {
    case 0: // 全部布防
        for (i = 0; i < 8; i++)
        {
            if ((g_qf_device.info.DZ_M_Defense[i] == 1) ||
                (g_qf_device.info.DZ_M_Defense[i] == 2) ||
                (g_qf_device.info.DZ_M_Defense[i] == 7) ||
                (g_qf_device.info.DZ_M_Defense[i] == 8))
            {
                g_qf_device.info.DZ_M_Defense[i] = 0;
            }
        }
        break;

    case 1: // 即时防区,可布撤防,不延时
        g_qf_device.info.DZ_M_Defense[number] = 0;
        break;
    case 2: // 留守防区,可布撤防,不延时
        g_qf_device.info.DZ_M_Defense[number] = 0;
        break;
    case 3: // 火警防区，不可撤防，不延时

        break;
    case 4: // 24小时防区，不可布撤防，不延时

        break;
    case 5: // 静音防区，不可布撤防，不延时

        break;
    case 6: // 紧急防区，不可布撤防，不延时

        break;
    case 7: // 延时防区,可布撤防,可延时
        g_qf_device.info.DZ_M_Defense[number] = 0;
        break;
    case 8: // 旁路防区，可布撤防,不延时
        g_qf_device.info.DZ_M_Defense[number] = 0;
        break;
    }
#endif
}

/**
 * @brief 设置防区类型
 * 根据给定的防区编号和类型，设置相应的防区属性。
 * @param number 防区编号
 * @param type 防区类型
 */
void Set_DefenceType(uint8_t number, uint8_t type)
{
#if USE_DEFENSE
    if ((number > SYS_DZ_NUMS) && (type < DZ_ATTR_INSTANT) && (type > DZ_ATTR_BYPASS))
    {
        return;
    }
    g_qf_device.info.DZ_M_Attributes[number] = type;
    switch (type)
    {
    case DZ_ATTR_INSTANT: // 即时防区

        break;
    case DZ_ATTR_HOLD: // 留守防区
        g_qf_device.info.DZ_M_Defense[number] = 1;
        break;
    case DZ_ATTR_FIRE: // 火警防区
        g_qf_device.info.DZ_M_Defense[number] = 1;
        break;
    case DZ_ATTR_24HOUR: // 24小时防区
        g_qf_device.info.DZ_M_Defense[number] = 1;
        break;
    case DZ_ATTR_SILENT: // 静音防区
        g_qf_device.info.DZ_M_Defense[number] = 1;
        break;
    case DZ_ATTR_EMERGENCY: // 紧急防区

        break;
    case DZ_ATTR_DELAY: // 延时防区

        break;
    case DZ_ATTR_BYPASS: // 旁路防区

        break;
    default:
        break;
    }
#endif
}

/**
 * @brief 解析网络参数
 * 将给定的字符串参数按照"."进行分割，并将分割后的子字符串转换为整数类型，存储到指定的数组中。
 * @param param 字符串参数
 * @param nums 存储整数的数组
 */
void parseNetworkParam(char *param, uint8_t *nums)
{
    char *token;
    int i = 0;
    // 使用strtok函数分割字符串
    token = strtok(param, ".");
    while (token != NULL)
    {
        nums[i] = atoi(token); // 将字符串转换为整数类型并存储到数组中
        nums[i] = nums[i] > 255 ? 255 : nums[i];
        i++;
        if (i > 4)
            break;
        token = strtok(NULL, ".");
    }
}
/**
 * @brief 判断数据有效性
 * 判断是否为全0或者全ff
 * @param input     输入数组
 * @param number    对比数据
 * @param num       数据个数
 * @Return  1:有效     0：无效
 */
uint8_t IsDataValidity(const uint8_t *input, uint8_t number, uint8_t num)
{

    while (num--)
    {
        if (*input != number)
        {
            return 1;
        }
        input++;
    }
    return 0;
}


/**
 * @brief 更新系统参数
 */
uint8_t TerParamUpdate(void)
{
    stmflash_write(USER_DATA_ADDR,(uint16_t *)&g_qf_device,sizeof(qf_dev_t));
    log_info("TerParamUpdate \n");
    return 0;
}

/**
 * @brief 系统软复位
 */
void Software_Reset(void)
{
    // 软件复位
    NVIC_SystemReset();
}

void Reset_PWD(void)
{
    // 重置密码
    memset(g_qf_device.info.PassWord, 0, 16);
    // 设置为临时密码
    memcpy(g_qf_device.info.PassWord, "admin", 5);
}

void Restore_Factory_Settings(void)
{
    // 重置出厂设置
    g_qf_device.state.Factory_Reset = 1;
    TerParamUpdate();
    HAL_Delay(10);
    Software_Reset();
}

uint16_t CRC16(uint8_t *data,uint16_t len)
{
    uint16_t crc = 0xFFFF;
    uint16_t i, j;
    for (j = 0; j < len; j++)
    {
        crc = crc ^ *(data + j);
        for (i = 0; i < 8; i++)
        {
            if ((crc & 0x0001) > 0)
            {
                crc >>= 1;
                crc ^= 0xa001;
            }
            else
                crc >>= 1;
        }
    }
    return (crc);
}

/**
 * @description: 解析数据，支队本数据格式使用CRC16校验
 * @param {uint8_t} *data
 * @param {uint16_t} DataSize
 * @return {*}
 */
uint8_t Check_Data(uint8_t *data, uint16_t DataSize)
{
    uint16_t crc = CRC16(data,DataSize - 6);
    if(data[0] == (char)0xC8 && data[1] == (char)0xD9 && data[2] == (char)0xE7 && data[3] == (char)0xD9 &&
        data[DataSize-6] == (char)(crc >> 8) && data[DataSize-5] == (char)(crc & 0xFF)
        )
    {
        return 1;
    }
    return 0;
}

